package com.bifrost.task.support;

import org.apache.commons.pool2.ObjectPool;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * Author by yanxiaobo
 * Date on 2018/6/12$.
 */
public class FTPClientPool implements ObjectPool<FtpConnectWrapper>{
    private static final int DEFAULT_POOL_SIZE = 10;

    private final BlockingQueue<FtpConnectWrapper> pool;
    private final FtpClientFactory factory;

    public FTPClientPool(FtpClientFactory factory) throws InterruptedException{
        this(DEFAULT_POOL_SIZE, factory);
    }

    public FTPClientPool(int poolSize, FtpClientFactory factory) throws InterruptedException{
        this.factory = factory;
        pool = new ArrayBlockingQueue<>(poolSize*2);
        initPool(poolSize);
    }

    private void initPool(int maxPoolSize) throws InterruptedException{
        for(int i=0;i<maxPoolSize;i++){
            //往池中添加对象
            addObject();
        }

    }

    public FtpConnectWrapper borrowObject() throws Exception {
        FtpConnectWrapper ftpConnectWrapper = pool.poll(3,TimeUnit.SECONDS);//从队列中拿出并从队列中删除

        if (ftpConnectWrapper == null) {//没有获取到，创建一个，并向连接池里面添加连接
            ftpConnectWrapper = (FtpConnectWrapper) factory.makeObject();

            addObject();
        }else if(!factory.validateObject(ftpConnectWrapper)){//验证不通过
            invalidateObject(ftpConnectWrapper);//使对象在池中失效
            //制造并添加新对象到池中
            ftpConnectWrapper = (FtpConnectWrapper) factory.makeObject();
            addObject();
        }
        return ftpConnectWrapper;

    }

    public void returnObject(FtpConnectWrapper client) throws Exception {
        if ((client != null) && !pool.offer(client,3,TimeUnit.SECONDS)) {//若归还不成功，直接销毁
                factory.destroyObject(client);
        }
    }

    @Override
    public void invalidateObject(FtpConnectWrapper obj) throws Exception {
        //移除无效的客户端
        pool.remove(obj);
    }

    @Override
    public void addObject() throws InterruptedException{
        //插入对象到队列
        pool.offer((FtpConnectWrapper) factory.makeObject(),3,TimeUnit.SECONDS);
    }

    @Override
    public int getNumIdle() {
        return 0;
    }

    @Override
    public int getNumActive() {
        return 0;
    }

    @Override
    public void clear() throws Exception, UnsupportedOperationException {

    }

    @Override
    public void close(){
        while(pool.iterator().hasNext()){
            try {
                FtpConnectWrapper ftpConnectWrapper = pool.take();
                factory.destroyObject(ftpConnectWrapper);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


}
